package com.tiantian.service.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tiantian.bean.PageBean;
import com.tiantian.cache.user.UserInfoCache;
import com.tiantian.dao.BusinessCapitalChangesDetailsRepository;
import com.tiantian.dao.BusinessUsersRepository;
import com.tiantian.dao.BuyerCapitalChangesDetailsRepository;
import com.tiantian.dao.BuyersUsersRepository;
import com.tiantian.dao.FundsChangeReasonRepository;
import com.tiantian.dao.PlatformCapitalChangesRepository;
import com.tiantian.dao.SpecialAccountChangeRepository;
import com.tiantian.dao.TaskinformationRepository;
import com.tiantian.dao.TasksOrdersRepository;
import com.tiantian.domain.Businesscapitalchangesdetails;
import com.tiantian.domain.BusinesscapitalchangesdetailsId;
import com.tiantian.domain.Businessusers;
import com.tiantian.domain.Buyercapitalchangesdetails;
import com.tiantian.domain.BuyercapitalchangesdetailsId;
import com.tiantian.domain.Buyerraisecashdetails;
import com.tiantian.domain.Buyersusers;
import com.tiantian.domain.Fundschangereason;
import com.tiantian.domain.SpecialAccountChange;
import com.tiantian.domain.Taskinformation;
import com.tiantian.domain.Tasksorders;
import com.tiantian.ret.Result;
import com.tiantian.service.BackstagelogService;
import com.tiantian.service.BusinessUsersService;
import com.tiantian.service.BuyerCapitalChangesDetailsService;
import com.tiantian.service.BuyerRaiseCashDetailsService;
import com.tiantian.service.BuyersUsersService;
import com.tiantian.service.CapitalService;
import com.tiantian.service.PlatformCapitalChangesService;
import com.tiantian.service.vo.SectionVo;
import com.tiantian.util.CommonConstant.QueryType;
import com.tiantian.util.ConditionResult;

/**
 * @description 资金管理
 */
@Service
@Transactional
public class CapitalServiceImpl implements CapitalService {
	@Autowired
	private BuyerCapitalChangesDetailsRepository repository;
	@Autowired
	private BuyersUsersRepository buyersUsersRepository;
	@Autowired
	private BusinessUsersRepository businessUsersRepository;
	@Autowired
	private BusinessCapitalChangesDetailsRepository businessCapitalChangesDetailsRepository;
	@Autowired
	private BuyerCapitalChangesDetailsRepository buyerCapitalChangesDetailsRepository;
	@Autowired
	private TasksOrdersRepository tasksOrdersRepository;
	@Autowired
	private TaskinformationRepository taskinformationRepository;
	@Autowired
	private PlatformCapitalChangesRepository platRepository;
	@Autowired
	private FundsChangeReasonRepository fundsChangeReasonRepository;
	@Autowired
	private SpecialAccountChangeRepository specialAccountChangeRepository;
	@Autowired
	private BackstagelogService backstagelogService;

	@Autowired
	private BuyerRaiseCashDetailsService raiseCaseService;

	@Autowired
	private BusinessUsersService businessUsersService;

	@Autowired
	private BuyersUsersService buyerUsersService;

	@Autowired
	private PlatformCapitalChangesService platformService;
	@Autowired
	private BuyerCapitalChangesDetailsService buyerDetailService;

	/**
	 * 获取平台资金明细列表
	 * 
	 * @param params
	 * @param page
	 * @return
	 */
	public List<Map<String, Object>> detailsList(Map<String, String> params, PageBean pageBean) {
		ConditionResult conditionResult = getQueryCondition(params, QueryType.LIST);

		List<Map<String, Object>> ret = repository.queryHumpListMapBySql(conditionResult.getSql(), pageBean.getStartIndex(), pageBean.getPageSize(),
				conditionResult.getParams());
		conditionResult = getQueryCondition(params, QueryType.COUNT);
		pageBean.setTotal(repository.queryCountBySql(conditionResult.getSql(), conditionResult.getParams()));
		return ret;
	}

	private ConditionResult getQueryCondition(Map<String, String> searchMap, QueryType type) {
		StringBuilder sql = new StringBuilder();
		Map<String, Object> params = new HashMap<String, Object>();

		switch (type) {
		case LIST:
			sql.append(" select t.*,e.ChangeReason");

			break;
		case COUNT:
			sql.append(" select count(1)");
			break;
		default:
			break;
		}
		sql.append(" from (");
		/*
		 * sql.append(" select a.*,e.ChangeReason,"); sql.append(
		 * " case when b.BusinessUserID is not null then b.BusinessUserID ");
		 * sql
		 * .append(" when c.BuyerUserID is not null then c.BuyerUserID end userId, "
		 * ); sql.append(
		 * " case when b.BusinessUserID is not null then b.ChangeAccount ");
		 * sql.append(
		 * " when c.BuyerUserID is not null then c.ChangeAccount end ChangeAccount ,"
		 * ); sql.append(" case when b.BusinessUserID is not null then '0' ");
		 * sql.append(" when c.BuyerUserID is not null then '1' end usertype ");
		 * sql.append(" from PlatformCapitalChanges a "); sql.append(
		 * " left join BusinessCapitalChangesDetails b on a.changeno=b.changeno"
		 * ); sql.append(
		 * " left join BuyerCapitalChangesDetails c on a.changeno=c.changeno");
		 * sql.append(
		 * " left join FundsChangeReason e on a.ChangeReasonId=e.ChangeReasonID"
		 * );
		 */

		sql.append(" select ChangeDate,BusinessUserID userid,ChangeAccount,paymentsdirection,");
		sql.append(" '0' usertype,ChangeReasonID,MoneyAmount,associateorderformid,associatetaskid,changebalance from BusinessCapitalChangesDetails ");
		sql.append(" union all");
		sql.append(" select ChangeDate, BuyerUserID userid,ChangeAccount,paymentsdirection,");
		sql.append(" '1' usertype,ChangeReasonID,MoneyAmount,associateorderformid,associatetaskid,changebalance from BuyerCapitalChangesDetails ");
		sql.append(" ) t left join FundsChangeReason e on t.ChangeReasonId=e.ChangeReasonID");
		sql.append(" where 1=1");
		if (searchMap != null) {

			if (StringUtils.isNotBlank(searchMap.get("changeAccount"))) {
				String[] str = StringUtils.split(searchMap.get("changeAccount"), "_");
				String userType = str[0];
				String changeAccount = str[1];
				sql.append(" and t.changeAccount = :changeAccount ");
				params.put("changeAccount", changeAccount.trim());
				sql.append(" and t.userType = :userType ");
				params.put("userType", userType.trim());
			}
			if (StringUtils.isNotBlank(searchMap.get("userId"))) {
				sql.append(" and t.userId like :userId ");
				params.put("userId", "%" + searchMap.get("userId").trim() + "%");
			}
			if (StringUtils.isNotBlank(searchMap.get("paymentsDirection"))) {
				sql.append(" and t.paymentsDirection = :paymentsDirection ");
				params.put("paymentsDirection", searchMap.get("paymentsDirection"));
			}
			if (StringUtils.isNotBlank(searchMap.get("associateTaskID"))) {
				sql.append(" and t.associateTaskID = :associateTaskID ");
				params.put("associateTaskID", searchMap.get("associateTaskID"));
			}
			if (StringUtils.isNotBlank(searchMap.get("minMoneyAmount"))) {
				sql.append(" and t.MoneyAmount >= :minMoneyAmount ");
				params.put("minMoneyAmount", searchMap.get("minMoneyAmount"));
			}
			if (StringUtils.isNotBlank(searchMap.get("maxMoneyAmount"))) {
				sql.append(" and t.MoneyAmount <= :maxMoneyAmount ");
				params.put("maxMoneyAmount", searchMap.get("maxMoneyAmount"));
			}
			if (StringUtils.isNotBlank(searchMap.get("startChangeDate"))) {
				sql.append(" and t.ChangeDate >= :startChangeDate ");
				params.put("startChangeDate", searchMap.get("startChangeDate"));
			}
			if (StringUtils.isNotBlank(searchMap.get("endChangeDate"))) {
				sql.append(" and t.ChangeDate <= :endChangeDate ");
				params.put("endChangeDate", searchMap.get("endChangeDate"));
			}
		}
		if (type == QueryType.LIST) {
			sql.append(" order by t.ChangeDate desc");
		}
		return new ConditionResult(sql.toString(), params);

	}

	/**
	 * 获取用户信息
	 * 
	 * @param userId
	 * @param userType
	 * @return
	 */
	public Result<Object> get(String userId, String userType) {
		Map<String, Object> ret = null;
		if (StringUtils.equals("1", userType)) {
			// 买手生财账户
			Buyersusers buyersuser = buyersUsersRepository.findOne(userId);
			if (buyersuser != null) {
				ret = new HashMap<>();
				ret.put("id", buyersuser.getBuyersUserId());
				ret.put("type", 1);
			}
		} else if (StringUtils.equals("2", userType)) {
			// 商家基本账户
			Businessusers businessUsers = businessUsersRepository.findOne(userId);
			if (businessUsers != null) {
				ret = new HashMap<>();
				ret.put("id", businessUsers.getBusinessUserId());
				ret.put("type", 2);
			}
		} else {
			return new Result<>(false, "请输入正确的用户类型");
		}
		if (ret == null) {
			return new Result<>(false, "查找的用户不存在");
		}
		return new Result<Object>(true, "查找成功", ret);
	}

	/**
	 * 执行划款
	 * 
	 * @param sectionVo
	 * @return
	 */
	public Result<Object> crossSection(SectionVo sectionVo) {

		Tasksorders tasksorders = tasksOrdersRepository.findOne(sectionVo.getOrderId().trim());
		if (tasksorders == null) {
			return new Result<>(false, "操作失败，订单ID未找到");
		}
		if (sectionVo.getTaskId() != null && !StringUtils.equals(tasksorders.getTaskId(), sectionVo.getTaskId().trim())) {
			return new Result<>(false, "任务ID和订单ID不匹配");
		}
		// 特殊账号原因
		SpecialAccountChange accountChange = new SpecialAccountChange();
		accountChange.setOperationUser(sectionVo.getUserType());
		accountChange.setOperationUserID(UserInfoCache.getCurrentUser().getUserId());
		accountChange.setAccountType("1");
		if (StringUtils.equals(sectionVo.getPaymentsDirection(), "1")) {
			accountChange.setDirectionMark("0");
		} else {
			accountChange.setDirectionMark("1");
		}
		accountChange.setChangeTime(new Date());
		accountChange.setChangeReason(sectionVo.getOpinion());
		specialAccountChangeRepository.save(accountChange);
		// 任务
		Taskinformation taskinformation = taskinformationRepository.findOne(sectionVo.getTaskId().trim());
		if (StringUtils.equals(sectionVo.getUserType(), "1")) {
			// 改变金额
			Buyersusers buyersUsers = buyersUsersRepository.findOne(sectionVo.getUserId().trim());
			if (StringUtils.equals(sectionVo.getPaymentsDirection(), "1")) {
				// +
				buyersUsers.setBasicAccount(buyersUsers.getBasicAccount().add(BigDecimal.valueOf(Double.valueOf(sectionVo.getAmount()))));
			} else {
				// -
				buyersUsers.setBasicAccount(buyersUsers.getBasicAccount().add(BigDecimal.valueOf(-Double.valueOf(sectionVo.getAmount()))));
			}
			buyersUsersRepository.save(buyersUsers);
			// 买手
			Buyercapitalchangesdetails detail = new Buyercapitalchangesdetails();
			BuyercapitalchangesdetailsId detailsId = new BuyercapitalchangesdetailsId();
			detailsId.setBuyerUserId(buyersUsers.getBuyersUserId());
			detailsId.setChangeDate(new Date());
			detailsId.setChangeNo(getBuyerChangeNo(buyersUsers.getBuyersUserId()));
			detail.setAssociateTaskId(tasksorders.getTaskId());
			detail.setAssociateOrderFormId(tasksorders.getOrderId());
			if (StringUtils.equals(taskinformation.getTaskType(), "4")) {
				detail.setTaskTypeMark('1');
			} else {
				detail.setTaskTypeMark('0');
			}
			detail.setChangeAccount('0');
			detail.setPaymentsDirection(StringUtils.equals(sectionVo.getPaymentsDirection(), "1") ? '1' : '0');
			detail.setMoneyAmount(BigDecimal.valueOf(Double.valueOf(sectionVo.getAmount())));
			detail.setChangeReasonId("23");
			detail.setChangeBalance(buyersUsers.getBasicAccount());
			detail.setId(detailsId);
			detail.setSACID(accountChange.getSACID());
			buyerCapitalChangesDetailsRepository.save(detail);

			backstagelogService.log("053", buyersUsers.getBuyersUserId(), "划款金额：" + detail.getMoneyAmount(), true);

			// 平台资金变动明细

			// Platformcapitalchanges platformChange = new
			// Platformcapitalchanges();
			// PlatformcapitalchangesId platformId = new
			// PlatformcapitalchangesId();
			// platformChange.setChangeDate(new Date());
			// platformChange.setChangeNo(detail.getId().getChangeNo());
			// platformChange.setId(platformId);
			// platformChange.setAssociateOrderFormId(detail.getAssociateOrderFormId());
			// platformChange.setAssociateTaskId(detail.getAssociateTaskId());
			// platformChange.setChangeBalance(detail.getChangeBalance());
			// platformChange.setChangeReasonId("23");
			// platformChange.setMoneyAmount(detail.getMoneyAmount());
			// platformChange.setPaymentsDirection(detail.getPaymentsDirection());
			// platformChange.setTaskTypeMark(detail.getTaskTypeMark());
			// platformChange.setSACID(accountChange.getSACID());
			// this.platRepository.save(platformChange);

			return new Result<>(true, "划款成功");
		} else if (StringUtils.equals(sectionVo.getUserType(), "2")) {
			// 改变金额
			Businessusers businessusers = businessUsersRepository.findOne(sectionVo.getUserId());
			if (StringUtils.equals(sectionVo.getPaymentsDirection(), "1")) {
				// +
				businessusers.setBasicAccount(businessusers.getBasicAccount().add(BigDecimal.valueOf(Double.valueOf(sectionVo.getAmount()))));
			} else {
				// -
				businessusers.setBasicAccount(businessusers.getBasicAccount().add(BigDecimal.valueOf(-Double.valueOf(sectionVo.getAmount()))));
			}
			businessUsersRepository.save(businessusers);

			// 商家
			Businesscapitalchangesdetails details = new Businesscapitalchangesdetails();
			BusinesscapitalchangesdetailsId detailsId = new BusinesscapitalchangesdetailsId();
			detailsId.setBusinessUserId(businessusers.getBusinessUserId());
			detailsId.setChangeDate(new Date());
			detailsId.setChangeNo(getChangeNo(businessusers.getBusinessUserId()));
			details.setAssociateTaskId(tasksorders.getTaskId());
			details.setAssociateOrderFormId(tasksorders.getOrderId());
			if (StringUtils.equals(taskinformation.getTaskType(), "4")) {
				details.setTaskTypeMark('1');
			} else {
				details.setTaskTypeMark('0');
			}
			details.setChangeAccount('0');
			details.setPaymentsDirection(StringUtils.equals(sectionVo.getPaymentsDirection(), "1") ? '1' : '0');
			details.setMoneyAmount(BigDecimal.valueOf(Double.valueOf(sectionVo.getAmount())));
			details.setChangeReasonId("23");
			details.setChangeBalance(businessusers.getBasicAccount());
			details.setId(detailsId);
			details.setSACID(accountChange.getSACID());
			businessCapitalChangesDetailsRepository.save(details);
			backstagelogService.log("054", businessusers.getBusinessUserId(), "划款金额：" + details.getMoneyAmount(), true);

			// 平台资金变动明细
			// Platformcapitalchanges platformChange = new
			// Platformcapitalchanges();
			// PlatformcapitalchangesId platformId = new
			// PlatformcapitalchangesId();
			// platformId.setChangeDate(new Date());
			//
			// platformId.setChangeNo(details.getId().getChangeNo());
			// platformChange.setId(platformId);
			// platformChange.setAssociateOrderFormId(details.getAssociateOrderFormId());
			// platformChange.setAssociateTaskId(details.getAssociateTaskId());
			// platformChange.setChangeBalance(details.getChangeBalance());
			// platformChange.setChangeReasonId("23");
			// platformChange.setMoneyAmount(details.getMoneyAmount());
			// platformChange.setPaymentsDirection(details.getPaymentsDirection());
			// platformChange.setTaskTypeMark(details.getTaskTypeMark());
			// platformChange.setSACID(accountChange.getSACID());
			// this.platRepository.save(platformChange);

			return new Result<>(true, "划款成功");
		}

		// 平台资金明细

		return new Result<>(false, "请输入正确的用户类型");
	}

	private int getBuyerChangeNo(String buyersUserId) {
		String data = getDayBegin(new Date());
		String sql = "select max(t.ChangeNo) from BuyerCapitalChangesDetails t where t.BuyerUserID=:BuyerUserID and t.ChangeDate>:ChangeDate";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("BuyerUserID", buyersUserId);
		params.put("ChangeDate", data);
		Long count = businessCapitalChangesDetailsRepository.queryCountBySql(sql, params);
		if (count == null) {
			return 1;
		} else {
			return count.intValue() + 1;
		}
	}

	private int getChangeNo(String businessUserId) {
		String data = getDayBegin(new Date());
		String sql = "select max(t.ChangeNo) from businesscapitalchangesdetails t where t.BusinessUserID=:businessUserId and t.ChangeDate>:changeDate";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("businessUserId", businessUserId);
		params.put("changeDate", data);
		Long count = this.platRepository.queryCountBySql(sql, params);
		if (count == null) {
			return 1;
		} else {
			return count.intValue() + 1;
		}
	}

	private String getDayBegin(Date date) {
		return DateFormatUtils.format(date, "yyyy-MM-dd 00:00:00");
	}

	public Result<Object> updateRaiseCash(char statusInfor, String buyersUserID, String raiseCashTime) {
		Map<String, String> param = new HashMap<>();
		param.put("buyersUserID", buyersUserID);
		param.put("raiseCashTime", raiseCashTime);
		List<Buyerraisecashdetails> list = this.raiseCaseService.getBuyerRaiseCashDetails(param);
		for (Buyerraisecashdetails temp : list) {
			temp.setStatusInfor(statusInfor);
			temp.setCompletionTime(new Date());
			if ('2' == statusInfor) {
				backstagelogService.log("052", temp.getId().getBuyersUserId(), "提现金额：" + temp.getMoneyAmout(), true);
			} else {
				backstagelogService.log("052", temp.getId().getBuyersUserId(), "提现金额：" + temp.getMoneyAmout(), false);
			}
			if ('2' == statusInfor) {
				// 通过提现，则修改买手的金额
				Buyersusers users = this.buyerUsersService.get(temp.getId().getBuyersUserId());
				BigDecimal amount = users.getBasicAccount();
				BigDecimal change = temp.getMoneyAmout();
				amount = amount.subtract(change);
				users.setBasicAccount(amount);
				this.buyerUsersService.save(users);

				Fundschangereason fundsChangeReason = new Fundschangereason();
				fundsChangeReason.setChangeReasonId("-1");
				fundsChangeReason.setUserType('1');
				fundsChangeReason.setAccountName("买手基本账户");
				fundsChangeReason.setChangeReason("用户提现");
				// this.fundsChangeReasonService.save(fundsChangeReason);
				// 买手资金变动明细
				Buyercapitalchangesdetails changeDetails = new Buyercapitalchangesdetails();
				BuyercapitalchangesdetailsId changeId = new BuyercapitalchangesdetailsId();
				changeId.setBuyerUserId(users.getBuyersUserId());
				changeId.setChangeDate(new Date());
				String platNo = this.platformService.getChangeNo(DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd"));
				changeId.setChangeNo(Integer.parseInt(platNo) + 1);
				changeDetails.setChangeAccount('0');
				changeDetails.setChangeBalance(users.getBasicAccount());
				changeDetails.setPaymentsDirection('0');
				changeDetails.setId(changeId);
				// fundsChangeReason.getChangeReasonId()
				changeDetails.setChangeReasonId("2");
				changeDetails.setAssociateOrderFormId(null);
				changeDetails.setAssociateTaskId(null);
				changeDetails.setMoneyAmount(temp.getMoneyAmout());
				// changeDetails.setSACID(0);
				this.buyerDetailService.save(changeDetails);

				// 平台资金变动明细
				// Platformcapitalchanges platformChange = new
				// Platformcapitalchanges();
				// PlatformcapitalchangesId platformId = new
				// PlatformcapitalchangesId();
				// platformId.setChangeDate(new Date());
				//
				// platformId.setChangeNo(Integer.parseInt(platNo) + 1);
				// platformChange.setId(platformId);
				// platformChange.setAssociateOrderFormId(null);
				// platformChange.setAssociateTaskId(null);
				// platformChange.setChangeBalance(users.getBasicAccount());
				// platformChange.setChangeReasonId(fundsChangeReason.getChangeReasonId());
				// platformChange.setMoneyAmount(temp.getMoneyAmout());
				// platformChange.setPaymentsDirection('0');
				// platformChange.setTaskTypeMark('0');
				// this.platformService.save(platformChange);
			}

		}
		this.raiseCaseService.save(list);
		return new Result<Object>(true, "操作成功");
	}

}
